using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;

namespace App
{
    //[Designer(typeof(CTabsDesigner))]
    public class CTabs : TabControl
    {
        private int mHoverindex;
        private bool mPressed;
        private ContextMenuStrip mMenu;

        public ContextMenuStrip RMenu
        {
            get { return mMenu; }
            set { mMenu = value; }
        }

        public CTabs()
        {
            this.SetStyle(ControlStyles.UserPaint, true);
            //this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            //this.SetStyle(ControlStyles.ResizeRedraw, true);
            //this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

            this.Size = new Size(116, 116);
            this.Padding = new System.Drawing.Point(8, 8);
            //this.HotTrack = true;
        }


        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);

            //if (!this.GetTabRect(0).Contains(e.X, e.Y) && this.Height == 26)
            //    this.Size = new Size(this.Width, this.mHeight);
        }
        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            base.OnMouseDoubleClick(e);

            //if (!this.GetTabRect(0).Contains(e.X, e.Y))
            //{
            //    this.height = this.Height;
            //    this.Size = new Size(this.Width, 26);
            //}
            //for (int i = 0; i < this.TabCount; i++)
            //{
            //    if (this.GetTabRect(i).Contains(e.X, e.Y))
            //    {
            //        if (i > 0 && TabPages[i].Controls.Count > 0)
            //        {
            //            for(int j = 0; j < this.TabPages[i].Controls.Count; j++)
            //            {
            //                this.TabPages[i].Controls[j].Dispose();
            //            }
            //            this.TabPages.RemoveAt(i);
            //        } 

            //        break;
            //    }
            //}
            if (SelectedIndex > 0)
            {
                this.Visible = false;
                this.SelectedTab.Dispose();
                this.SelectedIndex = TabPages.Count - 1;
                this.Visible = true;
            }
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            for (int i = 0; i < this.TabCount; i++)
            {
                if (this.GetTabRect(i).Contains(e.X, e.Y))
                {
                    this.mHoverindex = i;

                    break;
                }
            }
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (!DesignMode)
                {
                    TCHITTESTINFO HTI = new TCHITTESTINFO(e.X, e.Y);
                    TabPage hotTab = this.TabPages[SendMessage(this.Handle, TCM_HITTEST, IntPtr.Zero, ref HTI)];
                    if (hotTab != null && mMenu != null) this.ContextMenuStrip = mMenu;
                }
            }

            base.OnMouseDown(e);

            this.mPressed = true;
            //this.Invalidate();
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            this.ContextMenuStrip = null;
            base.OnMouseUp(e);

            this.mPressed = false;
            //this.Invalidate();
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            this.mHoverindex = -1;

            //this.Invalidate();
        }

        #region OnPaint
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
            e.Graphics.CompositingQuality = CompositingQuality.HighQuality;

            switch (Common.Theme)
            {
                case Common.ColorScheme.Blue:
                    {
                        e.Graphics.Clear(Common.PanelColorBack);

                        Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                        //if (this.Height > 26)
                        //{
                        //    DrawHelper.FillRoundRectangle(e.Graphics, new SolidBrush(Color.FromArgb(32, Color.Black)),
                        //        new Rectangle(5, this.Height - 20, this.Width - 10, 17), 3f);

                        //    DrawHelper.FillRoundRectangle(e.Graphics, new SolidBrush(Color.FromArgb(32, Color.Black)),
                        //        new Rectangle(5, this.Height - 20, this.Width - 10, 16), 3f);
                        //}
                        int ti = 0;
                        foreach (TabPage tab in this.TabPages)
                        {
                            Rectangle tabrect = this.GetTabRect(ti);
                            tabrect.Height += 4;
                            tabrect.Width -= 2;

                            if (this.SelectedIndex >= 0 && this.Height > 26 && tab == this.SelectedTab)
                            {
                                if (this.SelectedIndex == 0)
                                {
                                    tabrect.X += 2;
                                }
                                using (SolidBrush b = new SolidBrush(Color.FromArgb(32, Color.Black)))
                                {
                                    DrawHelper.FillTopRoundRectangle(e.Graphics, b,
                                        new Rectangle(tabrect.X - 2, tabrect.Y, tabrect.Width + 4, tabrect.Height + 4), 3f);
                                }

                                using (SolidBrush b = new SolidBrush(Color.FromArgb(16, Color.Black)))
                                {
                                    DrawHelper.FillTopRoundRectangle(e.Graphics, b,
                                        new Rectangle(tabrect.X - 1, tabrect.Y, tabrect.Width + 2, tabrect.Height + 4), 3f);
                                }

                                using (LinearGradientBrush b = new LinearGradientBrush(tabrect, Color.FromArgb(235, 243, 254), Color.FromArgb(220, 231, 245), LinearGradientMode.Vertical))
                                {
                                    DrawHelper.FillTopRoundRectangle(e.Graphics, b, tabrect, 3f);
                                }

                                DrawHelper.DrawTopRoundRectangle(e.Graphics, new Pen(Color.FromArgb(141, 178, 227)), tabrect, 3f);
                                tabrect.Offset(1, 1);
                                tabrect.Width -= 2;
                                tabrect.Height--;

                                using (LinearGradientBrush b = new LinearGradientBrush(tabrect, Color.FromArgb(248, 251, 255),
                                    Color.Transparent, LinearGradientMode.ForwardDiagonal))
                                {
                                    DrawHelper.DrawRoundRectangle(e.Graphics, new Pen(b), tabrect, 3f);
                                }

                                Region region = new Region();
                                region.Exclude(new Rectangle(tabrect.X - 4, 0, tabrect.Width + 1, 2));
                                tab.Region = region;
                            }
                            else if (ti == this.mHoverindex)
                            {
                                tabrect.Width--;

                                if (ti == 0)
                                {
                                    tabrect.X += 2;
                                    DrawHelper.RenderTopSelection(e.Graphics, tabrect, 3f, this.mPressed);
                                    tabrect.X -= 2;
                                }
                                else
                                    DrawHelper.RenderTopSelection(e.Graphics, tabrect, 3f, this.mPressed);

                                tabrect.Width++;
                            }

                            tabrect.Height -= 2;

                            StringFormat sf = new StringFormat();
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Center;

                            using (SolidBrush b = new SolidBrush(Color.FromArgb(21, 66, 139)))
                            {
                                e.Graphics.DrawString(tab.Text, tab.Font, b, tabrect, sf);
                            }

                            ti++;
                        }
                    }
                    break;
                case Common.ColorScheme.Custom:
                    {
                        e.Graphics.Clear(Common.Color);

                        Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                        if (this.Height > 26)
                        {
                            DrawHelper.FillRoundRectangle(e.Graphics, new SolidBrush(Color.FromArgb(32, Color.Black)),
                                new Rectangle(5, this.Height - 20, this.Width - 10, 17), 3f);
                            DrawHelper.FillRoundRectangle(e.Graphics, new SolidBrush(Color.FromArgb(32, Color.Black)),
                                new Rectangle(5, this.Height - 20, this.Width - 10, 16), 3f);
                        }

                        int ti = 0;
                        foreach (TabPage tab in this.TabPages)
                        {
                            Rectangle tabrect = this.GetTabRect(ti);
                            tabrect.Height += 4;

                            if (this.SelectedIndex >= 0 && this.Height > 26 && tab == this.SelectedTab)
                            {
                                DrawHelper.FillTopRoundRectangle(e.Graphics, new SolidBrush(Color.FromArgb(32, Color.Black)),
                                    new Rectangle(tabrect.X - 2, tabrect.Y, tabrect.Width + 4, tabrect.Height + 4), 3f);

                                DrawHelper.FillTopRoundRectangle(e.Graphics, new SolidBrush(Color.FromArgb(16, Color.Black)),
                                    new Rectangle(tabrect.X - 1, tabrect.Y, tabrect.Width + 2, tabrect.Height + 4), 3f);

                                DrawHelper.FillTopRoundRectangle(e.Graphics, new LinearGradientBrush(tabrect,
                                    DrawHelper.GetColor(1.085, Common.Color), DrawHelper.GetColor(1.025, Common.Color),
                                    LinearGradientMode.Vertical), tabrect, 3f);

                                DrawHelper.DrawTopRoundRectangle(e.Graphics, new Pen(DrawHelper.GetColor(0.75, Common.Color)), tabrect, 3f);
                                tabrect.Offset(1, 1);
                                tabrect.Width -= 2;
                                tabrect.Height--;
                                DrawHelper.DrawRoundRectangle(e.Graphics, new Pen(new LinearGradientBrush(tabrect,
                                    DrawHelper.GetColor(1.105, Common.Color), Color.Transparent, LinearGradientMode.ForwardDiagonal)), tabrect, 3f);

                                Region region = new Region();
                                region.Exclude(new Rectangle(tabrect.X - 4, 0, tabrect.Width + 1, 2));
                                tab.Region = region;

                            }
                            else if (ti == this.mHoverindex)
                            {
                                tabrect.Width--;

                                if (ti == 0)
                                {
                                    tabrect.Height -= 3;
                                    DrawHelper.RenderSelection(e.Graphics, tabrect, 3f, this.mPressed);
                                    tabrect.Height += 3;
                                }
                                else
                                    DrawHelper.RenderTopSelection(e.Graphics, tabrect, 3f, this.mPressed);

                                tabrect.Width++;
                            }

                            tabrect.Height -= 2;

                            StringFormat sf = new StringFormat();
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Center;

                            e.Graphics.DrawString(tab.Text, tab.Font, new SolidBrush(SystemColors.ControlText), tabrect, sf);

                            ti++;
                        }
                    }
                    break;
            }
        }
        #endregion


        private enum TCHITTESTFLAGS
        {
            TCHT_NOWHERE = 1,
            TCHT_ONITEMICON = 2,
            TCHT_ONITEMLABEL = 4,
            TCHT_ONITEM = TCHT_ONITEMICON | TCHT_ONITEMLABEL
        }

        private const int TCM_HITTEST = 0x130D;

        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        private struct TCHITTESTINFO
        {
            public Point pt;
            public TCHITTESTFLAGS flags;
            public TCHITTESTINFO(int x, int y)
            {
                pt = new Point(x, y);
                flags = TCHITTESTFLAGS.TCHT_ONITEM;
            }
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, ref TCHITTESTINFO lParam);

    }
}
